package cn.client

import android.util.Log
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import cn.client.data.ChatData
import cn.client.data.MsgDataItem
import cn.client.data.Person
import cn.client.data.localData.dao.UserDao
import cn.client.data.remoteData.WebSocketConfig
import cn.client.data.remoteData.bean.ChatMessage
import cn.client.data.remoteData.bean.WebSocketMessage
import cn.client.data.remoteData.repository.UserRepository
import cn.client.data.userStateManager
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import org.json.JSONObject
import javax.inject.Inject
import kotlinx.coroutines.delay


@HiltViewModel
class MainViewModel @Inject constructor(
    private val userDao: UserDao
) : ViewModel() {

    private val moshi: Moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    private val chatMessageAdapter: JsonAdapter<ChatMessage> =
        moshi.adapter(ChatMessage::class.java)

    private val jsonAdapter: JsonAdapter<WebSocketMessage> =
        moshi.adapter(WebSocketMessage::class.java)

    // 事件管道
    private val _pageEvents = Channel<PageEvent>(Channel.BUFFERED)

    // 可观察事件数据流
    val pageEvents = _pageEvents.receiveAsFlow()

    // 可变状态
    var pageStates by mutableStateOf(PageState())
        private set

    // 使用MutableStateFlow来存储uid
    private val _userId = MutableStateFlow<Int>(-1)
    val userId: StateFlow<Int> = _userId.asStateFlow()

    private val _onConnect = MutableStateFlow<Boolean>(false)
    val onConnect: StateFlow<Boolean> = _onConnect.asStateFlow()

    private var webSocketListener: WebSocketListener? = null
    private var webSocket: WebSocket? = null


    var chats by mutableStateOf(
        listOf(
            ChatData(
                person = Person(
                    id = 1,
                    name = "Ada",
                    avatar = R.drawable.ab1_inversions
                ),
                mutableStateListOf(
                    MsgDataItem(
                        from = Person(
                            id = 1,
                            name = "Ada",
                            avatar = R.drawable.ab1_inversions
                        ),
                        "Hello, here is Ada",
                        "2023-12-11"
                    ),
                    MsgDataItem(
                        from = Person(
                            id = 1,
                            name = "Ada",
                            avatar = R.drawable.ab1_inversions
                        ),
                        "Nice to meet you",
                        "2023-12-11"
                    )
                )
            ),
            ChatData(
                person = Person(
                    id = 1,
                    name = "Bob",
                    avatar = R.drawable.ab1_inversions
                ),
                mutableStateListOf(
                    MsgDataItem(
                        from = Person(
                            id = 2,
                            name = "Bob",
                            avatar = R.drawable.ab1_inversions
                        ),
                        "Hello, here is Bob",
                        "2023-12-11"
                    ).apply { read = false }
                )
            ),
        )
    )



    // 收集意图
    fun dispatch(intent: PageIntent) {
        when (intent) {
            is PageIntent.GetUser -> getUser(intent.msg)
            is PageIntent.ConnectToWebSocket -> connectWebSocket(intent.uid)
//            is PageIntent.DisconnectWebSocket -> disconnectWebSocket(intent.uid)
//            is PageIntent.SendMsg -> sendMsg(intent.msg)
            else -> {
                Unit
            }
        }
    }


    // 发起WebSocket连接的方法
    private fun connectWebSocket(uid: Int) {
        val thisUser: String = uid.toString()

        viewModelScope.launch {
            if (webSocket != null) {
                // 如果WebSocket已经打开，则不重复连接
                return@launch
            }

            // 创建OkHttpClient实例
            val client = OkHttpClient()
            // 创建WebSocketListener实例来处理WebSocket事件
            webSocketListener = object : WebSocketListener() {
                override fun onOpen(webSocket: WebSocket, response: Response) {
                    super.onOpen(webSocket, response)
                    // 连接成功打开时的处理
                    _onConnect.value = true
                }

                override fun onMessage(webSocket: WebSocket, text: String) {
                    super.onMessage(webSocket, text)
                    // 接收到消息时的处理
                }

                override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                    super.onFailure(webSocket, t, response)
                    _onConnect.value = false
                    // 连接失败时的处理
                    Log.e("WebSocket", "Connection failed", t) // 打印错误信息
                    if (response != null) {
                        Log.d("MainViewModel", "connectWebSocket方法异常：${response.message}")
                    }
                }

                override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                    super.onClosing(webSocket, code, reason)
                    // 连接正在关闭时的处理
                    _onConnect.value = false
                }

                override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                    super.onClosed(webSocket, code, reason)
                    // 连接已关闭时的处理
                    if (_onConnect.value) {
                        _onConnect.value = false
                    }
                    webSocketListener = null // 清除监听器引用
                    Log.e("WebSocket", "Connection closed with code $code and reason $reason") // 打印关闭信息
                     // 尝试重新连接
                }
            }
            // 构建WebSocket请求URL
            val request = Request.Builder()
                .url("ws://39.106.54.215:8080/chat?uid=$thisUser")
                .build()
            Log.d("MainViewModel", "websocket连接，uid: $thisUser")
            // 创建WebSocket连接
            webSocket = client.newWebSocket(request, webSocketListener as WebSocketListener)
        }
    }

    // 断开连接的方法
    private fun disconnectWebSocket() {
        if (_onConnect.value) {
            _onConnect.value = false
        }
        webSocket?.cancel()
    }


    // 查询本地缓存
    private fun getUser(msg: String) {
        Log.d("getUser", "消息：$msg")
        viewModelScope.launch {
            userDao.getUser().catch { e ->
                Log.d("MainViewModel", "错误：$e")
                _pageEvents.send(PageEvent.GetErr("错误：$e"))
            }.collect { it ->
                if (it != null) {
                    _userId.value = it.uid
                    _pageEvents.send(PageEvent.UserRes(uid = it.uid))
                } else {
                    _pageEvents.send(PageEvent.GetErr("查询失败"))
                }
            }
        }
    }

    /**
     * 意图集
     */
    sealed class PageIntent {
        data class SelectUser(val any: String) : PageIntent()
        data class ConnectToWebSocket(val uid: Int) : PageIntent()  // 连接WebSocket
        data class DisconnectWebSocket(val uid: Int) : PageIntent() // 断开连接
        data class SendMsg(val msg: ChatMessage) : PageIntent()  // 发送消息
        data class GetUser(val msg: String) : PageIntent()  // 查询本地缓存
    }

    /**
     * 事件集
     */
    sealed class PageEvent {
        data class Error(val error: String) : PageEvent()
        data class Success(val data: Any?) : PageEvent()
        data class UserLogin(val uid: Int) : PageEvent()
        data class UserRes(val uid: Int) : PageEvent()  // 本地缓存
        data class GetErr(val msg: String) : PageEvent() // 获取本地缓存失败
        data class WebSocketSending(val msg: String) : PageEvent() // 发起连接中
        data class WebSocketMiss(val msg: String) : PageEvent() // 连接失败
    }

    /**
     * 状态集
     */
    data class PageState(
        val uid: Int = -1
    )

    companion object {
        private const val RETRY_DELAY_MILLIS = 5000L // 重试间隔，例如5秒
    }


}